﻿<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Import Namespace="System.Data" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" Src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" Src="~/_controltemplates/ToolBarButton.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" Src="/_controltemplates/ButtonSection.ascx" %>

<script runat="server">
    private bool isLocked;
    private SPListItem task;

    public SPListItem Task
    {
        get
        {
            if (task == null)
            {
                task = GetItem(Request.QueryString["Site"], Request.QueryString["List"], Request.QueryString["Item"]);
            }
            return task;
        }
    }

    public bool IsLocked
    {
        get
        {
            isLocked = ((int)Task[SPBuiltInFieldId.WorkflowVersion] != 1);
            return isLocked;
        }
        set
        {
            isLocked = value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    public void UnlockButton_Click(object sender, System.EventArgs e)
    {
        using (SPWeb web = GetWeb(Request.QueryString["Site"]))
        {
            web.AllowUnsafeUpdates = true;
            Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest();
            SPSecurity.CodeToRunElevated unlockTask = new SPSecurity.CodeToRunElevated(UnlockTask);
            SPSecurity.RunWithElevatedPrivileges(unlockTask);
        }

    }

    public static bool AlterTask(SPListItem task, Hashtable htData, bool fSynchronous, int attempts, int millisecondsTimeout)
    {
        // check this link for more details: http://geek.hubkey.com/2007/09/locked-workflow.html   

        if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)
        {
            SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task[SPBuiltInFieldId.WorkflowListId].ToString())];
            SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);
            for (int i = 0; i < attempts; i++)
            {
                Microsoft.SharePoint.Workflow.SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];
                if (!workflow.IsLocked)
                {
                    task[SPBuiltInFieldId.WorkflowVersion] = 1;
                    task.SystemUpdate();
                    break;
                }
                if (i != attempts - 1)
                    System.Threading.Thread.Sleep(millisecondsTimeout);
            }
        }
        return Microsoft.SharePoint.Workflow.SPWorkflowTask.AlterTask(task, htData, fSynchronous);
    }

    protected void UnlockTask()
    {
        Hashtable ht = new Hashtable();
        AlterTask(Task, ht, true, 5, 100);
        IsLocked = false;
    }

    private SPWeb GetWeb(string siteUrl)
    {
        SPSite site = null;
        SPWeb web = null;
        string s1 = siteUrl.Substring(siteUrl.IndexOf("//") + 2);

        try
        {
            string s2 = s1.Substring(s1.IndexOf("/"));
            site = new SPSite(SPControl.GetContextSite(Context).ID);
            web = site.OpenWeb(s2);
        }
        catch
        {
            site = new SPSite(SPControl.GetContextSite(Context).ID);
            web = site.RootWeb;
        }

        return web;
    }

    private SPList GetList(string siteUrl, string listGuid)
    {
        SPWeb site = GetWeb(siteUrl);
        return site.Lists[new Guid(listGuid)];
    }

    private SPListItem GetItem(string siteUrl, string listGuid, string itemId)
    {
        SPList list = GetList(siteUrl, listGuid);
        return list.GetItemById(int.Parse(itemId));
    }

</script>

<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea">
    Unlock Task:
    <% Response.Write(Task.Title); %>
</asp:Content>
<asp:Content ID="Content3" runat="server" ContentPlaceHolderID="PlaceHolderPageDescription">
    Use this page to unlock the selected task item. You can only unlock a task if it
    is currently locked.
</asp:Content>
<asp:Content ID="Content4" runat="server" ContentPlaceHolderID="PlaceHolderMain">
    <br />
    <br />
    <br />
    <br />
    <table border="0" cellspacing="0" cellpadding="0" width="100%">
        <% if (IsLocked)
           { %>
        <tr>
            <td>
                <asp:Image runat="server" ToolTip="Task is locked" AlternateText="Task locked image"
                    ImageUrl="/_layouts/IMAGES/Simient.SharePoint.Features/lock.png" Height="48px"
                    Width="48px" />
            </td>
            <td>
                <asp:Label runat="server" ID="results" CssClass="ms-error" Text="This task is currently locked. Press Unlock button to unlock the task." />
                <wssuc:ButtonSection runat="server" ShowStandardCancelButton="true">
                    <template_buttons>
                        <asp:PlaceHolder runat="server">               
                            <asp:Button id="btnUnlock" UseSubmitBehavior="false" runat="server" class="ms-ButtonHeightWidth" 
                                    Text="Unlock" OnClick="UnlockButton_Click" />
                        </asp:PlaceHolder>
                    </template_buttons>
                </wssuc:ButtonSection>
            </td>
        </tr>
        <%}
           else
           { %>
        <tr>
            <td>
                &nbsp;<asp:Image runat="server" ToolTip="Task is unlocked" AlternateText="Task unlocked image"
                    Height="48px" Width="48px" ImageUrl="/_layouts/IMAGES/Simient.SharePoint.Features/unlock.png" />
            </td>
            <td>
                <asp:Label runat="server" ID="message" CssClass="ms-toolbar" Text="This task is not locked. Press Cancel button to go back." />
                <wssuc:ButtonSection runat="server" ShowStandardCancelButton="true">
                    <template_buttons>
                        <asp:PlaceHolder runat="server">
                        </asp:PlaceHolder>
                    </template_buttons>
                </wssuc:ButtonSection>
            </td>
        </tr>
        <%} %>
    </table>
</asp:Content>
